function varargout = TLBitwiseOperatorDlg(action, varargin)

% TL_BITWISEOPERATOR_DLG manages the user interface for TargetLink BitwiseOperator block
%
% SYNTAX dlgInfo = TLBitwiseoperatorDlg('GetDlgInfo');
%   gets dialog info of TargetLink BitwiseOperator block
%
%   INPUT ARGUMENTS
%   -/-      
%
%   OUTPUT ARGUMENTS
%   dlgInfo     dialog information contains pageNames etc.
%
% SYNTAX [sheetDims, ctrlPos] = ...
%           TLBitwiseoperatorDlg('CtrlPositions', pageName, commonGeom, dlgInfo, sheetDims);
%   calculates the control positions of all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   commonGeom      common geometry data
%   dlgInfo         dialog information contains pageNames etc.
%   sheetDims       dimension of sheet
%
%   OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% SYNTAX dlgdata = TLBitwiseoperatorDlg('Create', pageName, dlgfig, dlgdata);
%   creates all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX [dlgdata,bModified] = TLBitwiseoperatorDlg('Manage', pageName, dlgfig, dlgdata, pageAction);
%   manages all actions of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageAction      modified control of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%   bModified       flag = 1, if dialog data are modified, =0 otherwise
%
% SYNTAX dlgdata = TLBitwiseoperatorDlg('Update', dlgfig, dlgdata, pageNum);
%   updates all controls of dialog page: <pageNum>
%
%   INPUT ARGUMENTS
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageNum         number of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX TLBitwiseoperatorDlg('Apply', dlgfig, dlgdata);
%   writes current blockdata to block and DD
%
%   INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
%   OUTPUT ARGUMENTS
%   - / -


% Author(s): D. Andoleit, T. Pietzsch
% $RCSfile: TLBitwiseoperatorDlg.m $
% $ProjectName: e:/ARC/Components/HostSW/SimulinkBlocksets/TLBlocksets/CommonBlockset/CommonBlockset_SimBlocksUI/Sources/MSrc/project.pj $
% $Revision: 1.11 $
% $Date: 2011/07/21 15:19:49MESZ $
%
% Copyright ?2011 dSPACE GmbH. All rights reserved.


% switch-case block for possible actions
switch lower(action)
    case 'getdlginfo'
        [varargout{1:2}] = FcnGetDlgInfo(varargin{1});
    case 'ctrlpositions'
        [varargout{1:2}] = FcnCtrlPositions(varargin{:});
    case 'create'
        [varargout{1}]   = FcnCreate(varargin{:});
    case 'manage'
        [varargout{1:2}] = FcnManage(varargin{:});
    case 'managesystemicons',
        [varargout{1:2}] = FcnManageSystemIcons(varargin{:});
    case 'update'
        [varargout{1}]   = FcnUpdate(varargin{:});
    case 'apply'
        [varargout{1:2}] = FcnApply(varargin{:});
    otherwise
        error(['Invalid action "' action '"']);
end


%-----------------------------------------------------------------------------------------
% FcnManageSystemIcons manage actions of toolbar icons
%
% INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   action      action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageSystemIcons(dlgfig, dlgdata, action) %#ok

bModified = false;
switch action
    case 'EditCode'
        % look for associated production code file
        [codefile,blockstr] = get_codefile(dlgdata.model);
        if ~isempty(codefile)
            codeedit(codefile,blockstr);
        end

    case 'ViewCode'
        tl_create_links_to_model('ShowComputation',dlgdata.model, 'output');

    otherwise
        error('Invalid callback');

end % switch(action)


%--------------------------------------------------------------------------
% FcnGetDlgInfo gets dialog info of TargetLink bitset block
%
% INPUT ARGUMENTS
%   hBlock      current block handle
%
% OUTPUT ARGUMENTS
%   dlgInfo     dialog information contains pageNames etc.
%   tlData      TargetLink block data
%--------------------------------------------------------------------------
function [dlgInfo, tlData] = FcnGetDlgInfo(hBlock)

dlgInfo = tl_get_dlginfodefaults('tlsim');
        titleName = 'Bitwise Operator';
        pathinfo = tl_pathinfo(hBlock);
        dlgInfo.title = sprintf('TargetLink %s: %s', titleName, pathinfo.shortDisplayName);
dlgInfo.pageNames = {...
    'Output',...
    'Bit mask', ...
    'Logging', ...
    'Documentation'};
tlData = get_tlcg_data(hBlock);


%--------------------------------------------------------------------------
% FcnCtrlPositions calculates the cotrol positions of all controls of
% dialog page: <pageName>
%
% INPUT ARGUMENTS
%   pageName        name of current page
%   commonGeom      common geometrie data
%   dlgInfo         dialog information contains pageNames etc.
%   sheetDims       dimension of sheet
%   bCodeComment    should code comment be available
%   dlgdata         dialog data
%
% OUTPUT ARGUMENTS
%   sheetDims   modified dimension of sheet
%   ctrlPos     positions of controls
%--------------------------------------------------------------------------
function [sheetDims, ctrlPos] = FcnCtrlPositions(pageName, commonGeom, dlgInfo, sheetDims)  %#ok<INUSL>
% initialize output parameter                                
ctrlPos = [];                         
switch pageName
    case 'Output'
       [sheetDims,ctrlPos] = FcnCalcOutputControlPositions(commonGeom);
    case 'Bit mask'
        [sheetDims,ctrlPos] = FcnCalcBitmaskControlPositions(commonGeom);
    case 'Logging'
        [sheetDims,ctrlPos] = FcnCalcLoggingControlPositions(commonGeom, sheetDims);
    case 'Documentation'
        bTblBlock = 0;
        bCodeComment = 1;
        [sheetDims, ctrlPos] = TLManageDocCtrls('ctrlpos', commonGeom, ...
            sheetDims, bCodeComment, bTblBlock);
end


%--------------------------------------------------------------------------
% FcnCreate creates all controls of dialog page: <pageName>
%
% INPUT ARGUMENTS
%   pageName    name of current page
%   dlgfig      current figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnCreate(pageName, dlgfig, dlgdata)
pageNum  = strmatch(pageName, dlgdata.pageNames, 'exact');
switch pageName
    case 'Output'
        dlgdata = FcnCreateOutputControls(pageNum, dlgfig, dlgdata);
    case 'Bit mask'
        dlgdata = FcnCreateBitmaskControls(pageNum, dlgfig, dlgdata);
    case 'Logging'
        dlgdata = FcnCreateLoggingControls(pageNum, dlgfig, dlgdata);
    case 'Documentation'
        dlgdata = TLManageDocCtrls( ...
            'create', pageNum, dlgfig, dlgdata);
end
% ctrlPos are not needed anymore
dlgdata.pageData{pageNum}.ctrlPos = [];


%--------------------------------------------------------------------------
% FcnManage manage all actions of dialog page: <pageName>
%
% INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          name of current page
%   dlgdata         dialog data
%   pageAction      name of calling control
%
% OUTPUT ARGUMENTS
%   dlgdata     dialog data
%   bModified   flag = 1, if dialog data are modified, = 0 otherwise
%--------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManage(pageName, dlgfig, dlgdata, pageAction)
bModified = false;
pageNum    = strmatch(pageName,dlgdata.pageNames,'exact');
switch pageName
    case 'Output'
        [dlgdata, bModified] = FcnManageOutputControls(pageNum, dlgfig, ...
                                                        dlgdata,pageAction);
    case 'Bit mask'
        [dlgdata, bModified] = FcnManageBitmaskControls(pageNum, dlgfig, ...
                                                        dlgdata,pageAction);
    case 'Logging'
        [dlgdata, bModified] = FcnManageLoggingControls(pageNum, ...
                                                        dlgdata,pageAction);
    case 'Documentation'
         [dlgdata, bModified] = TLManageDocCtrls('callback', ...
                                        pageNum, dlgfig, dlgdata, pageAction);
end

%--------------------------------------------------------------------------
% FcnUpdate updates all controls of dialog page: <pageNum>
%
% INPUT ARGUMENTS
%   dlgfig          name of current page
%   dlgdata         dialog data
%   pagenum         number of current tab
%
% OUTPUT ARGUMENTS
%   dlgdata         dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnUpdate(dlgfig, dlgdata, pageNum)
pageName  = dlgdata.pageNames{pageNum};
switch pageName
    case 'Output'
        dlgdata = FcnUpdateOutputControls(dlgfig,dlgdata,pageNum);
    case 'Bit mask'
        dlgdata = FcnUpdateBitmaskControls(dlgfig,dlgdata,pageNum);
    case 'Logging'
        dlgdata = FcnUpdateLoggingControls(dlgfig,dlgdata,pageNum);
    case 'Documentation'
        TLManageDocCtrls('update', pageNum, dlgfig, dlgdata);
end

   
%--------------------------------------------------------------------------
% FcnApply writes current blockdata to block and DD
%
% INPUT ARGUMENTS
%   -/-
%
% OUTPUT ARGUMENTS
%   argout      return value is bContinue
%--------------------------------------------------------------------------
function [dlgdata, bClose] = FcnApply(dlgfig, dlgdata, bClose) %#ok<INUSL>

bExistOutputVar  = false;
bExistBitmaskVar = false;

if ~isempty(dlgdata.data.output.variable)
    bExistOutputVar = logical(dsdd('Exist', dlgdata.data.output.variable, ...
        'Parent',       '/Pool/Variables', ...
        'objectKind',   'Variable'));
end
if ~isempty(dlgdata.data.bitmask.variable)
    bExistBitmaskVar = logical(dsdd('Exist', dlgdata.data.bitmask.variable, ...
        'Parent',       '/Pool/Variables', ...
        'objectKind',   'Variable'));
end

if bExistOutputVar && ~bExistBitmaskVar
    if ~isempty(dlgdata.data.bitmask.variable)
        % only output value existing -> also use type of output for
        % bitmask, but only if it is an integer.
        isCompatible = tl_dsdddlgif( 'IsCompatible', ...
            'CurrentPath',  dlgdata.data.output.variable, ...
            'ObjectKind',   'Variable', ...
            'BlockType',    dlgdata.maskType, ...
            'BlockVar',     'output');    
                                    
        if isCompatible==0
            dlgdata.data.bitmask.type = dlgdata.data.output.type;        
        else
            typeSelection = tl_dsdddlgif( 'SelectObject', ...
                'CurrentPath',  dlgdata.data.bitmask.type, ...
                'ObjectKind',   'Typedef', ...
                'BlockType',    dlgdata.maskType, ...
                'BlockVar',     'bitmask');    

            if ~isempty(typeSelection)
                dlgdata.data.bitmask.type = typeSelection;
            end
        end
        tl_export_blockdata_dd(dlgdata.data,'BlockType',dlgdata.maskType,'BlockHandle',dlgdata.model);
    end
elseif ~bExistOutputVar && bExistBitmaskVar
    if ~isempty(dlgdata.data.output.variable)
        % only bitmask value existing -> also use type of bitmask for
        % output, but only if it is an integer.
        isCompatible = tl_dsdddlgif( 'IsCompatible', ...
            'CurrentPath',  dlgdata.data.bitmask.variable, ...
            'ObjectKind',   'Variable', ...
            'BlockType',    dlgdata.maskType, ...
            'BlockVar',     'bitmask');    
        if isCompatible==0
            dlgdata.data.output.type = dlgdata.data.bitmask.type;        
        else
            typeSelection = tl_dsdddlgif( 'SelectObject', ...
                'CurrentPath',  dlgdata.data.output.type, ...
                'ObjectKind',   'Typedef', ...
                'BlockType',    dlgdata.maskType, ...
                'BlockVar',     'output');    
            if ~isempty(typeSelection)
                dlgdata.data.bitmask.type = typeSelection;
            end
        end
        tl_export_blockdata_dd(dlgdata.data,'BlockType',dlgdata.maskType,'BlockHandle',dlgdata.model);
    end
elseif ~bExistOutputVar && ~bExistBitmaskVar
    if ~isempty(dlgdata.data.output.variable) || ~isempty(dlgdata.data.bitmask.variable)
        % no value existing -> ask for datatype
         typeSelection = tl_dsdddlgif( 'SelectObject', ...
                'CurrentPath',  dlgdata.data.output.type, ...
                'ObjectKind',   'Typedef', ...
                'BlockType',    dlgdata.maskType, ...
                'BlockVar',     'output');    
        if isempty(typeSelection)
        else
            dlgdata.data.output.type = typeSelection;
            dlgdata.data.bitmask.type = typeSelection;
            % create variable objects (output and bitmask) in data dictionary
            tl_export_blockdata_dd(dlgdata.data,'BlockType',dlgdata.maskType,'BlockHandle',dlgdata.model);
        end
    end
end
[dlgdata, bClose] = tl_apply_blockdata(dlgdata, bClose);


%-----------------------------------------------------------------------------------------
% FcnCalcOutputControlPositions calculates positions for all controls on output page
%
% INPUT ARGUMENTS
%   commonGeom      common geometrie information
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function [sheetDims,ctrlPos] = FcnCalcOutputControlPositions(commonGeom)

% calculate positions of output controls
excludedCtrls = {'allscaling','inheritproperties', 'castoutput', 'width', ...
                'element', 'scaling', 'scalarExp', 'unit', 'type'};
[sheetDims, ctrlPos, colOutputFrame, colDelta, rowDelta] =  ...
    tl_calc_ctrls_positions(commonGeom, excludedCtrls);

% adapt box cordinates in consideration of missing unit controls
ctrlPos.descEdit(3) = ctrlPos.nameEdit(1) + ctrlPos.nameEdit(3) + ctrlPos.nameMenuButton(3) ...
                            - ctrlPos.descEdit(1);

% recalculate group boxes' width
groupBoxWidth = ctrlPos.descEdit(1) + ctrlPos.descEdit(3) + commonGeom.frameSideEdgeBuffer;
ctrlPos.tlcgoptGroupbox(3) = groupBoxWidth;

ctrlPos = FcnCalcOperationControlPositions(commonGeom, ctrlPos, colOutputFrame, colDelta, rowDelta);

% calculate sheet Dimensions
width = ctrlPos.tlcgoptGroupbox(3) ...
    + 2 * commonGeom.frameSideEdgeBuffer;
height = ctrlPos.tlcgoptGroupbox(4) ...
    + ctrlPos.operationGroupbox(4) ...
    + 2 * commonGeom.textHeight ...
    + commonGeom.sheetBottomEdgeBuffer;

sheetDims = [width height];

%-----------------------------------------------------------------------------------------
% FcnCalcBitmaskControlPositions calculates positions for all controls on Bitmask page
%
% INPUT ARGUMENTS
%   commonGeom      common geometrie information
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function [sheetDims,ctrlPos] = FcnCalcBitmaskControlPositions(commonGeom)

% calculate positions of output controls
excludedCtrls = {'allscaling','inheritproperties', 'castoutput', 'width', ...
                'element', 'scaling', 'scalarExp', 'unit', 'type'};
[sheetDims, ctrlPos, colOutputFrame, colDelta, rowDelta] =  ...
    tl_calc_ctrls_positions(commonGeom, excludedCtrls);

% adapt box cordinates in consideration of missing unit controls
ctrlPos.descEdit(3) = ctrlPos.nameEdit(1) + ctrlPos.nameEdit(3) + ctrlPos.nameMenuButton(3) ...
                            - ctrlPos.descEdit(1);

% recalculate group boxes' width
groupBoxWidth = ctrlPos.descEdit(1) + ctrlPos.descEdit(3) + commonGeom.frameSideEdgeBuffer;
ctrlPos.tlcgoptGroupbox(3) = groupBoxWidth;

% sheet dimensions
width = ctrlPos.tlcgoptGroupbox(3) ...
    + 2 * commonGeom.frameSideEdgeBuffer;
height = ...
    + ctrlPos.tlcgoptGroupbox(4) ...
    + 3 * commonGeom.textHeight ...
    + 2 * rowDelta ...
    + commonGeom.sheetBottomEdgeBuffer ...
    + commonGeom.sheetTopEdgeBuffer;
sheetDims = [width height];


%-----------------------------------------------------------------------------------------
% FcnCalcOperationControlPositions calculates positions for all controls on Bitmask page
%
% INPUT ARGUMENTS
%   commonGeom      common geometrie information
%   yDelta          moves all controls in y direction
%   width           width of the operation groupbox
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function ctrlPos = FcnCalcOperationControlPositions(commonGeom, ...
                                ctrlPos, colOutputFrame, colDelta, rowDelta)
    
% define an additional box for bitIndex
ctrlPos.operationGroupbox(1) = ctrlPos.tlcgoptGroupbox(1);
ctrlPos.operationGroupbox(2) = ctrlPos.tlcgoptGroupbox(2) + ...
    ctrlPos.tlcgoptGroupbox(4) + commonGeom.textHeight;
ctrlPos.operationGroupbox(3) = ctrlPos.tlcgoptGroupbox(3);
ctrlPos.operationGroupbox(4) = 2 * commonGeom.editHeight + rowDelta +...
    commonGeom.frameTopEdgeBuffer + commonGeom.frameBottomEdgeBuffer;

strings_and_styles = {...
    'Use bit mask',             'checkbox'; ...
    'Operator:',                'text'; ...
    'NAND',                     'popupmenu'; ...
    '+'                         'pushbutton'};

    [bitwiseUsebitmaskCheckBoxSize, ...
    operatorLabelSize, ...
    bitwiseOperatorPopupSize, ...
    inputsButtonSize] = ...
    ds_get_uicontrol_sizes(commonGeom,strings_and_styles);

% finetune some results
inputsButtonSize = inputsButtonSize .* [1 0.5];

% numinputsLabel
cx = colOutputFrame(1);
cy = commonGeom.frameBottomEdgeBuffer;
ctrlPos.numinputsLabel = [cx cy operatorLabelSize];

% bitwiseNumofinputsEdit
cx = colOutputFrame(2);
width = colOutputFrame(4) - colOutputFrame(2) - colDelta/3 - inputsButtonSize(1);
height = commonGeom.editHeight;
ctrlPos.bitwiseNumofinputsEdit = [cx cy width height];        

% up and down buttons
cx = cx + ctrlPos.bitwiseNumofinputsEdit(3);
ctrlPos.bitwiseInputsUpButton = ...
    [cx (cy + commonGeom.editHeight/2) inputsButtonSize];
ctrlPos.bitwiseInputsDownButton = ...
    [cx cy inputsButtonSize];

% bitwiseBitmaskEdit
cx = colOutputFrame(4);
height = commonGeom.editHeight;
width = ctrlPos.addressEdit(1) + ctrlPos.addressEdit(3) - cx;
ctrlPos.bitwiseBitmaskEdit = [cx cy width height];

% operatorLabel
cx = colOutputFrame(1);
cy = cy + rowDelta + commonGeom.editHeight;
ctrlPos.operatorLabel = [cx cy operatorLabelSize];

% bitwiseOperatorPopup
cx = colOutputFrame(2);
width = colOutputFrame(4) - colOutputFrame(2) - colDelta/3;
height = commonGeom.editHeight;
ctrlPos.bitwiseOperatorPopup = [cx cy width height];

% bitwiseUsebitmaskCheckBox
cx = colOutputFrame(4);
ctrlPos.bitwiseUsebitmaskCheckBox = [cx cy bitwiseUsebitmaskCheckBoxSize];
    

%-----------------------------------------------------------------------------------------
% FcnCalcLoggingControlPositions calculates positions for all controls on logging page
%
% INPUT ARGUMENTS
%   commonGeom      common geometrie information
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function [sheetDims,ctrlPos] = FcnCalcLoggingControlPositions(commonGeom, sheetDims)
excludedCtrls = {'autoscaling'};
[sheetDims, ctrlPos] = ...
    TLManageLoggingCtrls('calcCtrls', commonGeom, sheetDims, excludedCtrls);

% to adapt the logging control positions to the output controls, first
% caculate the position of the output controls
[sheetDims, outputCtrlPos] = FcnCalcOutputControlPositions(commonGeom);

% adapt the contols
ctrlPos.logPopup(1)     = outputCtrlPos.varEdit(1);
ctrlPos.logPopup(3)     = outputCtrlPos.varMenuButton(1) + outputCtrlPos.varMenuButton(3) - outputCtrlPos.varEdit(1);
ctrlPos.plotEdit(1)     = ctrlPos.logPopup(1);
ctrlPos.plotEdit(3)     = ctrlPos.logPopup(3);
ctrlPos.samplesLabel(1) = outputCtrlPos.addressLabel(1);
ctrlPos.samplesEdit(1)  = ctrlPos.samplesLabel(1) + ...
                            ctrlPos.samplesLabel(3) + commonGeom.frameDelta;
ctrlPos.samplesEdit(3)  = outputCtrlPos.addressEdit(1) + ...
                            outputCtrlPos.addressEdit(3) - ctrlPos.samplesEdit(1);
ctrlPos.logplotGroupbox(3) = outputCtrlPos.tlcgoptGroupbox(3);
                        

%-----------------------------------------------------------------------------------------
% FcnCreateOutputControls creates the figure window
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateOutputControls(pageNum,dlgfig,dlgdata)

Children = dlgdata.pageData{pageNum}.children;
ctrlPos  = dlgdata.pageData{pageNum}.ctrlPos;
pageName = dlgdata.pageNames{pageNum};

% create bit index group box
Children.operationGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {'Operation'}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.operationGroupbox);

% create operation controls
% Tag is needed for developer test
Children.bitwiseUsebitmaskCheckBox = uicontrol( ...
    'Tag',              'bitwiseUsebitmaskCheckBoxO', ...
    'Parent',           Children.operationGroupbox, ...
    'Style',            'checkbox', ...
    'Value',            1, ...
    'String',           'Use bit mask', ...
    'Position',         ctrlPos.bitwiseUsebitmaskCheckBox, ...
    'Callback',         sprintf('tldlg(''%s'',gcbf,''bitwiseUsebitmaskCheckBox'')',pageName));
% Tag is needed for developer test
Children.bitwiseBitmaskEdit = uicontrol( ...
    'Tag',              'bitwiseBitmaskEditO', ...
    'Parent',           Children.operationGroupbox, ...
    'BackgroundColor',  'w', ...
    'Style',            'edit', ...
    'String',           'bin2dec(''11011001'')', ...
    'Position',         ctrlPos.bitwiseBitmaskEdit, ...
    'Callback',         sprintf('tldlg(''%s'',gcbf,''bitwiseBitmaskEdit'')',pageName));
Children.operatorLabel = uicontrol( ...
    'Parent',           Children.operationGroupbox, ...
    'Style',            'text', ...
    'String',           'Operator:', ...
    'Position',         ctrlPos.operatorLabel);

% get string for popup menu
popupString = FcnGetOperators;
% Tag is needed for developer test
Children.bitwiseOperatorPopup = uicontrol( ...
    'Tag',              'bitwiseOperatorPopupO', ...
    'Parent',           Children.operationGroupbox, ...
    'Style',            'popupmenu', ...
    'Value',            1, ...
    'BackgroundColor',  'w', ...
    'String',           popupString, ...
    'Position',         ctrlPos.bitwiseOperatorPopup, ...
    'Callback',         sprintf('tldlg(''%s'',gcbf,''bitwiseOperatorPopup'')',pageName));
Children.numinputsLabel = uicontrol( ...
    'Parent',           Children.operationGroupbox, ...
    'Style',            'text', ...
    'String',           'Inputs:', ...
    'Position',         ctrlPos.numinputsLabel);
% Tag is needed for developer test
userData = struct('min', 1, 'max', 2^31-1);
Children.bitwiseNumofinputsEdit = uicontrol( ...
    'Tag',              'bitwiseNumofinputsEditO', ...
    'Parent',           Children.operationGroupbox, ...
    'BackgroundColor',  'w', ...
    'Style',            'edit', ...
    'String',           '1', ...
    'UserData',         userData, ...
    'Position',         ctrlPos.bitwiseNumofinputsEdit, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''bitwiseNumofinputsEdit'')',pageName));
% Tag is needed for developer test
Children.bitwiseInputsUpButton = uicontrol( ...
    'Tag',              'bitwiseInputsUpButtonO', ...
    'Parent',             Children.operationGroupbox, ...
    'Style',              'pushbutton', ...
    'String',             '+', ...
    'Position',           ctrlPos.bitwiseInputsUpButton, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''bitwiseInputsUpButton'')',pageName));
% Tag is needed for developer test
Children.bitwiseInputsDownButton = uicontrol( ...
    'Tag',              'bitwiseInputsDownButtonO', ...
    'Parent',             Children.operationGroupbox, ...
    'Style',              'pushbutton', ...
    'String',             '-', ...
    'Position',           ctrlPos.bitwiseInputsDownButton, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''bitwiseInputsDownButton'')',pageName));

dlgdata.pageData{pageNum}.children = Children;

% create standard variable controls
dlgdata = TLManageVariableCtrls('create', pageNum, dlgfig, dlgdata);
% modify panel title
set(dlgdata.pageData{pageNum}.children.tlcgoptGroupbox, 'Title', 'Output');


%-----------------------------------------------------------------------------------------
% FcnCreateBitmaskControls creates the figure window
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateBitmaskControls(pageNum,dlgfig,dlgdata)

% create standard variable controls
dlgdata = TLManageVariableCtrls('create', pageNum, dlgfig, dlgdata);
% modify panel title
set(dlgdata.pageData{pageNum}.children.tlcgoptGroupbox, 'Title', 'Bit mask');


%-----------------------------------------------------------------------------------------
% FcnCreateLoggingControls creates the figure window
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateLoggingControls(pageNum,dlgfig,dlgdata)
% create logging controls
dlgdata = TLManageLoggingCtrls('create', pageNum, dlgfig, dlgdata);

%-----------------------------------------------------------------------------------------
% FcnManageOutputControls manages control actions of output page
%
% INPUT ARGUMENTS
%   pageNum         number of current page
%   dlgfig          handle for dialog figure
%   dlgdata         dialog data
%   pageAction      action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%   bModified       flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageOutputControls(pageNum,dlgfig,dlgdata,action)
switch action
    case {'bitwiseOperatorPopup', 'bitwiseUsebitmaskCheckBox', 'bitwiseNumofinputsEdit', ...
            'bitwiseInputsUpButton', 'bitwiseInputsDownButton', 'bitwiseBitmaskEdit'}
        [dlgdata, bModified] = FcnManageOperationControls(pageNum, dlgdata, action);
    otherwise 
            [dlgdata, bModified] = TLManageVariableCtrls( ...
                        'manage', pageNum, dlgfig, dlgdata, action, 'output');
end

%-----------------------------------------------------------------------------------------
% FcnManageBitmaskControls manages control actions of Bitmask page
%
% INPUT ARGUMENTS
%   pageNum         number of current page
%   dlgfig          handle for dialog figure
%   dlgdata         dialog data
%   action      action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%   bModified       flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageBitmaskControls(pageNum, dlgfig, dlgdata, action)
    [dlgdata, bModified] = TLManageVariableCtrls( ...
                        'manage', pageNum, dlgfig, dlgdata, action, 'bitmask');


%-----------------------------------------------------------------------------------------
% FcnManageOperationControls manages control actions of operation boxes of the
% tabs 'Output' and 'Bit mask'. The  function is used by manage
% functions of the tabs 'Output' and 'Bit mask', because they operate 
% on the same 'Operation'-values.
%
% INPUT ARGUMENTS
%   pageNum         number of current page
%   dlgdata         dialog data
%   action          action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%   bModified       flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageOperationControls(pageNum, dlgdata, action)
Children = dlgdata.pageData{pageNum}.children;
bModified = false;
switch action
    case 'bitwiseOperatorPopup'
        operators = FcnGetOperators;
        newValue = get(Children.bitwiseOperatorPopup, 'Value');
        newOperator = operators{newValue};
        if ~strcmp(dlgdata.data.operator, newOperator)
            dlgdata.data.operator = newOperator;
            bModified = true;
        end
    case 'bitwiseUsebitmaskCheckBox' 
        bSelected = get(Children.bitwiseUsebitmaskCheckBox, 'Value');
        if bSelected ~= dlgdata.data.usebitmask
            dlgdata.data.usebitmask = bSelected;
            bModified = true;
        end
    case {'bitwiseNumofinputsEdit', 'bitwiseInputsUpButton', 'bitwiseInputsDownButton'}
        [numinputs, bModified] = tl_handle_editupdown( 'manage', ...
            dlgdata.data.numinputs, [Children.bitwiseNumofinputsEdit, ...
            Children.bitwiseInputsUpButton, Children.bitwiseInputsDownButton], ...
            Children.(action));
        if bModified
            dlgdata.data.numinputs = num2str(numinputs);
        end
    case 'bitwiseBitmaskEdit'
        newBitmask = get(Children.bitwiseBitmaskEdit, 'String');
        if ~strcmp(dlgdata.data.bitmask.value, newBitmask)
            dlgdata.data.bitmask.value = newBitmask;
            bModified = true;
        end
end


%-----------------------------------------------------------------------------------------
% FcnManageLoggingControls manages control actions of Logging page
%
% INPUT ARGUMENTS
%   pageNum         number of current page
%   dlgdata         dialog data
%   pageAction      action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%   bModified       flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageLoggingControls(pageNum,dlgdata,action)
[dlgdata, bModified] = TLManageLoggingCtrls('manage', pageNum, dlgdata, action, 'logdata');


%-----------------------------------------------------------------------------------------
% FcnUpdateOutputControls updates output controls
%
% INPUT ARGUMENTS
%   dlgfig          figure handle of dialog
%   dlgdata         dialog data
%   pageNum         page Number
%
% OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnUpdateOutputControls(dlgfig,dlgdata,pageNum)

% update all controls
dlgdata =   TLManageVariableCtrls('update', pageNum, dlgdata, 'output');
dlgdata =   TLManageLoggingCtrls('update', pageNum, dlgdata,'logdata','output');
Children = dlgdata.pageData{pageNum}.children;

% if field "variable" is not empty, check if it has already an error. If it has
% no error, check if it has the right data type in the DD.
if ~strcmp(dlgdata.data.output.variable, '')
    % check if variable edit has already an error
    userData = get(Children.varEdit, 'UserData');
    errorCode = userData.ctrlStatus.iserror;
    % if variable has no error, check if its type is integer in DD
    if errorCode==0
        variableFlag = tl_dsdddlgif( 'IsCompatible', ...
            'CurrentPath',  dlgdata.data.output.variable, ...
            'ObjectKind',   'Variable', ...
            'BlockType',    dlgdata.maskType, ...
            'BlockVar',     'output');    

        % if variable exists in DD and has a wrong data type
        if variableFlag == 2
            userData.ctrlStatus.iserror = 1;
            set(Children.varEdit, 'UserData', userData);
            % set new error code
        end
    end
end

% set controls
TLManageVariableCtrls('setCtrls', pageNum, dlgfig, dlgdata);
TLManageLoggingCtrls('setCtrls',pageNum, dlgfig, dlgdata);
FcnUpdateOperationControls(dlgfig, dlgdata, pageNum);


%-----------------------------------------------------------------------------------------
% FcnUpdateBitmaskControls updates Bitmask controls
%
% INPUT ARGUMENTS
%   dlgfig          figure handle of dialog
%   dlgdata         dialog data
%   pageNum         page Number
%
% OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnUpdateBitmaskControls(dlgfig,dlgdata,pageNum)

% update all controls
dlgdata =   TLManageVariableCtrls('update', pageNum, dlgdata, 'bitmask');
Children = dlgdata.pageData{pageNum}.children;
% if field "variable" is not empty, check if it has already an error. If it has
% no error, check if it has the right data type in the DD.
if ~strcmp(dlgdata.data.bitmask.variable, '')
    % check if variable edit has already an error
    userData = get(Children.varEdit, 'UserData');
    errorCode = userData.ctrlStatus.iserror;
    % check if inserted variable exists in the DD and if it is an Integer
    % in case that the edit field has no error before.
    if errorCode==0
    variableFlag = tl_dsdddlgif( 'IsCompatible', ...
            'CurrentPath',  dlgdata.data.bitmask.variable, ...
            'ObjectKind',   'Variable', ...
            'BlockType',    dlgdata.maskType, ...
            'BlockVar',     'bitmask');  
        % if variable exists in DD and has a wrong data type
        if variableFlag == 2
            userData.ctrlStatus.iserror = 1;
            set(Children.varEdit, 'UserData', userData);
            % set new error code
        end
    end
end
% set controls
TLManageVariableCtrls('setCtrls', pageNum, dlgfig, dlgdata);

%-----------------------------------------------------------------------------------------
% FcnUpdateOperationControls updates the controls of operation boxes of the
% tabs 'Output' and 'Bit mask'. The  function is used by the update 
% functions of tabs 'Output' and 'Bit mask', because they operate 
% on the same 'Operation'-values.
%
% INPUT ARGUMENTS
%   dlgfig          figure handle of dialog
%   dlgdata         dialog data
%   pageNum         page number 
%
% OUTPUT ARGUMENTS
%   -/-
%--------------------------------------------------------------------------
function FcnUpdateOperationControls(dlgfig, dlgdata, pageNum)

Children = dlgdata.pageData{pageNum}.children;
    
% bitwiseOperatorPopup
userData = get(Children.bitwiseOperatorPopup, 'UserData');
% get string for popup menu
operators = FcnGetOperators;
userData.ctrlStatus = struct(   'enable',   'on', ...
                                'value',    find(strcmp(operators, dlgdata.data.operator)), ...
                                'string',   {operators});
set(Children.bitwiseOperatorPopup, 'UserData', userData);

% bitwiseUsebitmaskCheckBox
if strcmp(dlgdata.data.operator, 'NOT')
    enable = 'off';
else
    enable = 'on';
end
userData = get(Children.bitwiseUsebitmaskCheckBox, 'UserData');
userData.ctrlStatus = struct('enable', enable, 'value', dlgdata.data.usebitmask);
set(Children.bitwiseUsebitmaskCheckBox, 'UserData', userData);

% numinputsEdit, upButton, downButton
states.edit = 'off';
states.up   = 'off';
states.down = 'off';
isValid = true;
if ~strcmp(dlgdata.data.operator, 'NOT') && dlgdata.data.usebitmask == false
    states = tl_handle_editupdown('update', dlgdata.data.numinputs, ...
                                            dlgdata, pageNum, 'bitwiseNumofinputsEdit');
    if ~states.isValid
        isValid = false;
    end
end
% numinputsEdit
userData = get(Children.bitwiseNumofinputsEdit, 'UserData');
userData.ctrlStatus = struct('enable', states.edit, 'string', dlgdata.data.numinputs );
if ~isValid
    % wrong input (maybe inserted outside the dialog) -> color text red
    userData.ctrlStatus.iserror = true;
end
set(Children.bitwiseNumofinputsEdit, 'UserData', userData);
% upButton
userData = get(Children.bitwiseInputsUpButton, 'UserData');
userData.ctrlStatus = struct('enable', states.up);
set(Children.bitwiseInputsUpButton, 'UserData', userData);
% downButton
userData = get(Children.bitwiseInputsDownButton, 'UserData');
userData.ctrlStatus = struct('enable', states.down);
set(Children.bitwiseInputsDownButton, 'UserData', userData);

% bitwiseBitmaskEdit
if strcmp(dlgdata.data.operator, 'NOT') || ~dlgdata.data.usebitmask
    enable = 'off';
else
    enable = 'on';
end
userData = get(Children.bitwiseBitmaskEdit, 'UserData');
userData.ctrlStatus = struct('enable', enable, 'string', dlgdata.data.bitmask.value );
set(Children.bitwiseBitmaskEdit, 'UserData', userData);
    
operationControls = {'bitwiseOperatorPopup', 'bitwiseUsebitmaskCheckBox', ...
                    'bitwiseNumofinputsEdit', 'bitwiseInputsUpButton', 'bitwiseInputsDownButton', ...
                    'bitwiseBitmaskEdit'};
TLSetCtrlsStatus(dlgfig, Children, operationControls);


%-----------------------------------------------------------------------------------------
% FcnUpdateLoggingControls updates output controls
%
% INPUT ARGUMENTS
%   dlgfig          figure handle of dialog
%   dlgdata         dialog data
%   pageNum         page Number
%
% OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnUpdateLoggingControls(dlgfig,dlgdata,pageNum)
dlgdata =   TLManageLoggingCtrls('update', pageNum, dlgdata,'logdata','output');
TLManageLoggingCtrls('setCtrls',pageNum, dlgfig, dlgdata);


%-----------------------------------------------------------------------------------------
% FcnGetOperators       returns the possible operators for operator popup
%                       menu
%
% INPUT ARGUMENTS
%   -/-
%
% OUTPUT ARGUMENTS
%   operators           list with operators
%--------------------------------------------------------------------------
function operators = FcnGetOperators()
operators = {'AND' 'OR' 'NAND' 'NOR' 'XOR' 'NOT'};

